#pragma once
#include <memory>
#include <map>
#include <mutex>
#include <condition_variable>
#include <future>
#include <functional>
#include "VideoScenesInItem.h"
#include "mixer/VideoScenesOutItem.h"
#include "encoder/VEncoder.h"
#include "source/output/OutputSource.h"
#include "AVFrame.h"
#include "Pal/VideoCompose.h"

namespace Media{

    class VideoMixer{
    public:
        using Ptr = std::shared_ptr<VideoMixer>;
        VideoMixer();
        ~VideoMixer();
        bool Start();
        bool Stop();

        bool AddItem(uint32_t itemId, const VideoScenesInItemConfig& config);
        bool SetItem(uint32_t itemId, const VideoScenesInItemConfig& config);
        bool DelItem(uint32_t itemId);
        bool GetItems(std::map<uint32_t, VideoScenesInItemConfig>& items);
        bool GetOneInItem(uint32_t itemId, VideoScenesInItemConfig& config);
        
        bool SetOutConfig(const VideoScenesOutItemConfig& config);
        bool GetOutConfig(VideoScenesOutItemConfig& config);
        bool AddOutSource(OutputSource::OutputSourceId id,const std::string& name); 
        bool RemoveOutSource(OutputSource::OutputSourceId id);


        bool SetDefaultOutCb(std::function<void (const FrameCommon::Frame::Ptr&)> cb);
    private:
        void packetProc(const FrameCommon::Frame::Ptr& frame);
        void frameProc();

        bool m_isRunning;
        // std::mutex m_cvMux;
        // std::condition_variable m_cv;

        std::future<void> m_frameProcTask;
        std::future<void> m_packetProcTask;

        std::recursive_mutex m_mux;
        std::map<uint32_t, VideoScenesInItem::Ptr> m_inItems;
        
        VideoScenesOutItemConfig m_outConfig;
        std::map<uint32_t, std::string> m_outSources;  

        VEncoder::Ptr m_encoder;

        VideoComposeObj* m_vCompose;

        std::function<void (const FrameCommon::Frame::Ptr&)> m_deaultOutCb;
    };
}
